package com.example.backend.service;

import com.example.backend.domain.entity.TicketCategory;
import com.example.backend.repository.TicketCategoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 工单分类树形结构管理服务
 * 支持多级分类的创建、查询和管理
 */
@Service
@Transactional
public class TicketCategoryTreeService {

    @Autowired
    private TicketCategoryRepository categoryRepository;

    /**
     * 分类树节点DTO
     */
    public static class CategoryTreeNode {
        private Long id;
        private String categoryName;
        private String categoryCode;
        private String description;
        private Long parentId;
        private String parentName;
        private Integer sortOrder;
        private Boolean isActive;
        private Integer level;
        private List<CategoryTreeNode> children;
        private Long ticketCount;
        private String fullPath;

        // 构造函数
        public CategoryTreeNode() {
            this.children = new ArrayList<>();
        }

        public CategoryTreeNode(TicketCategory category) {
            this();
            this.id = category.getId();
            this.categoryName = category.getCategoryName();
            this.categoryCode = category.getCategoryCode();
            this.description = category.getDescription();
            this.parentId = category.getParent() != null ? category.getParent().getId() : null;
            this.parentName = category.getParent() != null ? category.getParent().getCategoryName() : null;
            this.sortOrder = category.getSortOrder();
            this.isActive = category.getIsActive();
            this.level = 0; // 将在构建树时设置
        }

        // Getters and Setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public String getCategoryName() { return categoryName; }
        public void setCategoryName(String categoryName) { this.categoryName = categoryName; }
        public String getCategoryCode() { return categoryCode; }
        public void setCategoryCode(String categoryCode) { this.categoryCode = categoryCode; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public Long getParentId() { return parentId; }
        public void setParentId(Long parentId) { this.parentId = parentId; }
        public String getParentName() { return parentName; }
        public void setParentName(String parentName) { this.parentName = parentName; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
        public Boolean getIsActive() { return isActive; }
        public void setIsActive(Boolean isActive) { this.isActive = isActive; }
        public Integer getLevel() { return level; }
        public void setLevel(Integer level) { this.level = level; }
        public List<CategoryTreeNode> getChildren() { return children; }
        public void setChildren(List<CategoryTreeNode> children) { this.children = children; }
        public Long getTicketCount() { return ticketCount; }
        public void setTicketCount(Long ticketCount) { this.ticketCount = ticketCount; }
        public String getFullPath() { return fullPath; }
        public void setFullPath(String fullPath) { this.fullPath = fullPath; }
    }

    /**
     * 构建完整的分类树
     * 
     * @return 分类树根节点列表
     */
    public List<CategoryTreeNode> buildCategoryTree() {
        List<TicketCategory> allCategories = categoryRepository.findAll();
        return buildCategoryTree(allCategories);
    }

    /**
     * 构建活跃的分类树
     * 
     * @return 活跃分类树根节点列表
     */
    public List<CategoryTreeNode> buildActiveCategoryTree() {
        List<TicketCategory> activeCategories = categoryRepository.findByIsActiveTrueOrderBySortOrderAsc();
        return buildCategoryTree(activeCategories);
    }

    /**
     * 构建分类树
     * 
     * @param categories 分类列表
     * @return 分类树根节点列表
     */
    private List<CategoryTreeNode> buildCategoryTree(List<TicketCategory> categories) {
        // 转换为节点
        Map<Long, CategoryTreeNode> nodeMap = categories.stream()
            .collect(Collectors.toMap(
                TicketCategory::getId,
                CategoryTreeNode::new
            ));

        List<CategoryTreeNode> rootNodes = new ArrayList<>();

        // 构建树结构
        for (CategoryTreeNode node : nodeMap.values()) {
            if (node.getParentId() == null) {
                // 根节点
                rootNodes.add(node);
                buildNodePath(node, nodeMap);
            } else {
                // 子节点
                CategoryTreeNode parent = nodeMap.get(node.getParentId());
                if (parent != null) {
                    parent.getChildren().add(node);
                    buildNodePath(node, nodeMap);
                }
            }
        }

        // 设置层级和排序
        for (CategoryTreeNode root : rootNodes) {
            setNodeLevel(root, 0);
            sortChildren(root);
        }

        return rootNodes;
    }

    /**
     * 构建节点路径
     * 
     * @param node 节点
     * @param nodeMap 节点映射
     */
    private void buildNodePath(CategoryTreeNode node, Map<Long, CategoryTreeNode> nodeMap) {
        StringBuilder path = new StringBuilder(node.getCategoryName());
        Long parentId = node.getParentId();
        
        while (parentId != null) {
            CategoryTreeNode parent = nodeMap.get(parentId);
            if (parent != null) {
                path.insert(0, parent.getCategoryName() + " > ");
                parentId = parent.getParentId();
            } else {
                break;
            }
        }
        
        node.setFullPath(path.toString());
    }

    /**
     * 设置节点层级
     * 
     * @param node 节点
     * @param level 层级
     */
    private void setNodeLevel(CategoryTreeNode node, int level) {
        node.setLevel(level);
        for (CategoryTreeNode child : node.getChildren()) {
            setNodeLevel(child, level + 1);
        }
    }

    /**
     * 对子节点排序
     * 
     * @param node 节点
     */
    private void sortChildren(CategoryTreeNode node) {
        node.getChildren().sort(Comparator.comparing(CategoryTreeNode::getSortOrder));
        for (CategoryTreeNode child : node.getChildren()) {
            sortChildren(child);
        }
    }

    /**
     * 获取分类的完整路径
     * 
     * @param categoryId 分类ID
     * @return 完整路径
     */
    public String getCategoryFullPath(Long categoryId) {
        Optional<TicketCategory> categoryOpt = categoryRepository.findById(categoryId);
        if (categoryOpt.isEmpty()) {
            return "";
        }

        TicketCategory category = categoryOpt.get();
        List<String> pathParts = new ArrayList<>();
        pathParts.add(category.getCategoryName());

        TicketCategory parent = category.getParent();
        while (parent != null) {
            pathParts.add(0, parent.getCategoryName());
            parent = parent.getParent();
        }

        return String.join(" > ", pathParts);
    }

    /**
     * 获取分类的所有子分类（包括子子分类）
     * 
     * @param categoryId 分类ID
     * @return 所有子分类ID列表
     */
    public List<Long> getAllSubCategoryIds(Long categoryId) {
        List<Long> subCategoryIds = new ArrayList<>();
        collectSubCategoryIds(categoryId, subCategoryIds);
        return subCategoryIds;
    }

    /**
     * 递归收集子分类ID
     * 
     * @param categoryId 分类ID
     * @param subCategoryIds 子分类ID列表
     */
    private void collectSubCategoryIds(Long categoryId, List<Long> subCategoryIds) {
        List<TicketCategory> children = categoryRepository.findByParentIdAndIsActiveTrueOrderBySortOrderAsc(categoryId);
        for (TicketCategory child : children) {
            subCategoryIds.add(child.getId());
            collectSubCategoryIds(child.getId(), subCategoryIds);
        }
    }

    /**
     * 检查是否可以删除分类
     * 
     * @param categoryId 分类ID
     * @return 是否可以删除
     */
    public boolean canDeleteCategory(Long categoryId) {
        // 检查是否有子分类
        List<TicketCategory> children = categoryRepository.findByParentIdAndIsActiveTrueOrderBySortOrderAsc(categoryId);
        if (!children.isEmpty()) {
            return false;
        }

        // 检查是否有工单使用此分类
        // 这里需要注入TicketRepository来检查
        // 暂时返回true，实际使用时需要实现
        return true;
    }

    /**
     * 移动分类到新的父分类
     * 
     * @param categoryId 分类ID
     * @param newParentId 新父分类ID
     * @return 是否成功
     */
    public boolean moveCategory(Long categoryId, Long newParentId) {
        Optional<TicketCategory> categoryOpt = categoryRepository.findById(categoryId);
        if (categoryOpt.isEmpty()) {
            return false;
        }

        TicketCategory category = categoryOpt.get();

        // 检查是否会形成循环引用
        if (newParentId != null && wouldCreateCircularReference(categoryId, newParentId)) {
            return false;
        }

        // 更新父分类
        if (newParentId == null) {
            category.setParent(null);
        } else {
            Optional<TicketCategory> parentOpt = categoryRepository.findById(newParentId);
            if (parentOpt.isPresent()) {
                category.setParent(parentOpt.get());
            } else {
                return false;
            }
        }

        categoryRepository.save(category);
        return true;
    }

    /**
     * 检查是否会形成循环引用
     * 
     * @param categoryId 分类ID
     * @param newParentId 新父分类ID
     * @return 是否会形成循环引用
     */
    private boolean wouldCreateCircularReference(Long categoryId, Long newParentId) {
        if (categoryId.equals(newParentId)) {
            return true;
        }

        List<Long> subCategoryIds = getAllSubCategoryIds(categoryId);
        return subCategoryIds.contains(newParentId);
    }

    /**
     * 获取分类的层级深度
     * 
     * @param categoryId 分类ID
     * @return 层级深度
     */
    public int getCategoryDepth(Long categoryId) {
        Optional<TicketCategory> categoryOpt = categoryRepository.findById(categoryId);
        if (categoryOpt.isEmpty()) {
            return 0;
        }

        int depth = 0;
        TicketCategory category = categoryOpt.get();
        while (category.getParent() != null) {
            depth++;
            category = category.getParent();
        }

        return depth;
    }

    /**
     * 搜索分类
     * 
     * @param keyword 关键词
     * @return 匹配的分类列表
     */
    public List<CategoryTreeNode> searchCategories(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return buildActiveCategoryTree();
        }

        List<TicketCategory> categories = categoryRepository.searchByKeyword(keyword);
        return buildCategoryTree(categories);
    }

    /**
     * 获取分类统计信息
     * 
     * @return 分类统计信息
     */
    public Map<String, Object> getCategoryStatistics() {
        long totalCategories = categoryRepository.count();
        long activeCategories = categoryRepository.findByIsActiveTrueOrderBySortOrderAsc().size();
        long rootCategories = categoryRepository.findByParentIdIsNullAndIsActiveTrueOrderBySortOrderAsc().size();

        return Map.of(
            "totalCategories", totalCategories,
            "activeCategories", activeCategories,
            "rootCategories", rootCategories,
            "maxDepth", getMaxDepth()
        );
    }

    /**
     * 获取最大层级深度
     * 
     * @return 最大深度
     */
    private int getMaxDepth() {
        List<TicketCategory> allCategories = categoryRepository.findAll();
        int maxDepth = 0;
        
        for (TicketCategory category : allCategories) {
            int depth = getCategoryDepth(category.getId());
            maxDepth = Math.max(maxDepth, depth);
        }
        
        return maxDepth;
    }
}
